package com.jk1.bianligou.blg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jk1.bianligou.blg.common.ErrorCode;
import com.jk1.bianligou.blg.domain.dto.cart.AmountChange;
import com.jk1.bianligou.blg.domain.po.Cart;
import com.jk1.bianligou.blg.domain.po.Item;
import com.jk1.bianligou.blg.domain.vo.CartVO;
import com.jk1.bianligou.blg.exception.BizException;
import com.jk1.bianligou.blg.mapper.CartMapper;
import com.jk1.bianligou.blg.service.CartService;
import com.jk1.bianligou.blg.service.ItemService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author WHH
 * @description 针对表【cart(购物车表)】的数据库操作Service实现
 * @createDate 2025-04-11 21:57:01
 */
@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart>
        implements CartService {

    @Resource
    private ItemService itemService;

    @Override
    public List<CartVO> getCartById(Long loginUserId) {
        //缓存机制...
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<Cart>()
                .eq("user_id", loginUserId)
                .eq("is_delete", 0);
        List<Cart> list = list(queryWrapper);
        return list.stream().map(CartVO::cartPO2VO).peek(cartVO -> {
            Long itemId = cartVO.getItemId();
            Item item = itemService.getById(itemId);
            cartVO.setItemName(item.getName());
            cartVO.setPrice(item.getPrice().multiply(BigDecimal.valueOf(cartVO.getQuantity())));
        }).sorted(Comparator.comparingInt(CartVO::getQuantity)).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean decreaseCart(AmountChange amountChange, Long loginUserId) {
        Long itemId = amountChange.getItemId();
        int amount = amountChange.getAmount();
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("item_id", itemId).eq("user_id", loginUserId);
        Cart cart = getOne(queryWrapper);
        //先查出来商品在不在购物车中
        if (cart != null) {
            //如果在 扣减数量(原子操作)
            Integer quantity = cart.getQuantity();
            if (quantity < amount) {
                throw new BizException(ErrorCode.PARAMS_ERROR, "商品数量不足");
            }
            //基于CAS乐观锁的实现 缺点：可能产生ABA问题
            boolean success = update()
                    .eq("id", cart.getId())
                    .eq("item_id", cart.getItemId())
                    .eq("quantity", quantity)
                    .eq("is_delete", 0)
                    .eq("user_id", loginUserId)
                    .setSql("quantity = quantity -" + amount).update();
            //成功返回true
            if (success) {
                //数量为0 删除商品(设置不可见)
                if (quantity == amount) {
                    cart.setIsDelete(true);
                    boolean b = updateById(cart);
                    if (!b) {
                        throw new BizException(ErrorCode.SYSTEM_ERROR);
                    }
                }
            } else {
                throw new BizException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            //如果不在直接返回
            throw new BizException(ErrorCode.NOT_FOUND_ERROR);
        }
        return true;
    }

    @Override
    public Boolean increaseCart(AmountChange amountChange, Long loginUserId) {
        Long itemId = amountChange.getItemId();
        int amount = amountChange.getAmount();
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("item_id", itemId).eq("user_id", loginUserId);
        Cart cart = getOne(queryWrapper);
        if (cart != null) {
            //如果在 增加数量(原子操作)
            Integer quantity = cart.getQuantity();
            //基于CAS乐观锁的实现 缺点：可能产生ABA问题
            boolean success = update()
                    .eq("id", cart.getId())
                    .eq("item_id", cart.getItemId())
                    .eq("quantity", quantity)
                    .eq("user_id", loginUserId)
                    .setSql("quantity = quantity +" + amount).update();
            if (success) {
                //成功如果发现不可见
                if (cart.getIsDelete()) {
                    cart.setIsDelete(false);
                    boolean b = updateById(cart);
                    if (!b) {
                        throw new BizException(ErrorCode.SYSTEM_ERROR);
                    }
                }
            } else {
                throw new BizException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            //如果不在添加一个
            //校验是否存在
            Item item = itemService.getById(itemId);
            if (item == null) {
                throw new BizException(ErrorCode.PARAMS_ERROR, "该商品不存在");
            }
            Cart add = new Cart();
            add.setUserId(loginUserId);
            add.setItemId(itemId);
            add.setQuantity(amount);
            boolean save = save(add);
            if (!save) {
                throw new BizException(ErrorCode.SYSTEM_ERROR);
            }
        }
        return true;
    }

    @Override
    public void clearCart(Long userId) {
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        boolean remove = remove(queryWrapper);
        if (!remove) {
            throw new BizException(ErrorCode.SYSTEM_ERROR);
        }
    }
}




